from datetime import datetime, timedelta
from doctest import debug
import io
from math import fabs
from nt import write
import os
import pathlib
import queue
import sys
import threading
from turtle import width

import boto3
from botocore.vendored.six import class_types
from dotenv import load_dotenv
import gradio as gr
from gradio.components import Chatbot
from numpy import str_

from gga_utils.common import *

sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
load_dotenv()  # 添加这行

# 添加项目根目录到Python路径
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from LLM.openaillm import OpenAIChat
from LLM.awsllm import AwsLLM
from vecstore.vecstore import *  # 新增导入
from Embeddings.FlagEmbeddingsWrapper import FlagEmbeddingsWrapper

# # 初始化主题
# set_theme = adjust_theme()
# 初始化AWS客户端
llm = AwsLLM()
# 初始化OpenAI客户端
# llm = OpenAIChat()
MAX_CONTEXT_LENGTH = 4096
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
embeddings = FlagEmbeddingsWrapper()

# 初始化向量存储
vec_store = VecStore(embeddings=embeddings)
try:
    vec_store.initialize()
    vectorstore = vec_store.load()
except Exception as e:
    logger.critical(f"系统启动失败: {str(e)}")
    exit(1)

def converse(history):
     # 直接返回生成器对象
    return llm.converse_stream(history)

        
def bot(history):
    try:
        partial_response = ""
          # 将最后一项user信息添加上context
        user_message = history[-1]["content"]
        context, sources = get_context_and_sources(user_message, vec_store, MAX_CONTEXT_LENGTH, logger)
        # 复制历史对话记录
        conversation = history.copy()
        # 修改最后一项user的content信息，添加上context
        conversation[-1] = {
            "role": "user",
            "content": f"请根据以下上下文用中文回答问题：\n<context>\n{context}\n</context>\n问题：{user_message}"
        }
          # 处理流式响应
        stream = converse(conversation)  # 获取生成器对象
        # 处理流式响应
        for text_chunk in stream:
            partial_response += text_chunk
            # 更新历史记录（保留之前的所有对话）
            updated_history = history[:-1] + [
                {"role": "user", "content": history[-1]["content"]},
                {"role": "assistant", "content": partial_response}
            ]
            yield updated_history
        
        # 获取最终历史数据
        final_history = history + [{"role": "assistant", "content": partial_response}]
        if state_gid.value:
            add_conversation_with_gid_to_json(state_gid.value,None, final_history)
            
        # yield final_history
        # print(get_last_conversation_content())
        # timer.start()
    except Exception as e:
        error_msg = f"ERROR: {str(e)}"
        error_history = history + [{"role": "assistant", "content": error_msg}]
        yield error_history



def user(user_message, history):
    return "", history + [{"role": "user", "content": user_message}]


script_content = open('web/js/head.js', 'r', encoding='utf-8').read()
head = f"""
  <script>
  {script_content}
  </script>
"""
state_gid= gr.State()
base_url = 'web/'
port = int(os.getenv('PORT')) if os.getenv('PORT') else None
def load_historylist(selected_name: str = None):
    # 获取当前 GID 对应的所有对话名称
    His_choice_cache = get_all_conversation_names_by_key(state_gid.value)
    
    # 如果传入了 selected_name 且该名称在选项中，则使用它作为当前选中值
    if selected_name and selected_name in His_choice_cache:
        current_select_value = selected_name
    else:
        current_select_value = list_vali_check(His_choice_cache)
    
    return gr.Radio(
        #label="Dialog Box",
        show_label=False,
        interactive=True,
        min_width=100,
        value=current_select_value,
        choices=His_choice_cache,
        elem_id="history-select-dropdown"
    )
# 获取gid参数
def load_userinfo(request: gr.Request):
    # 获取gid参数
    state_gid.value = request.query_params.get('gid')
    print(f"当前GID参数值: {state_gid.value}")
     
    # 获取多个参数
    params = dict(request.query_params)
    print("所有URL参数:", params)
    # 新增刷新逻辑
    return load_historylist()
def create_chat_cache_key():
    if state_gid.value:
        return state_gid.value + "_" + datetime.now().strftime("%Y%m%d%H%M%S")
    else:
        return None 

def new_conversation_to_json():
    if state_gid.value:
        add_conversation_with_gid_to_json(state_gid.value,create_chat_cache_key(),None)
def get_last_conversation_content_with_gid():
    if state_gid.value:
       return get_last_conversation_content_by_key(state_gid.value)
def get_selected_conversation_content_with_gid_handle(name:str):
    if state_gid.value:
       return get_selected_conversation_content_with_gid(state_gid.value,name)
def delete_conversation_with_gid_from_json_handle(name:str):
    if state_gid.value: 
        delete_conversation_with_gid_from_json(state_gid.value,name)
def input_box_submit_handle(onversation:list[list]):
    selected_name= update_conversation_name_with_gid_to_json(state_gid.value,onversation)
    return load_historylist(selected_name)

with gr.Blocks(
    title="Chat Room",
    css_paths='web/style/style.css',
    head=head
) as demo:
    # 添加状态管理组件
    
    chat_his = gr.State([])
    # 原按钮图标路径错误：r"UI\imgs\background.jpg"
    gr.Button("Chat Room", icon="web/imgs/background.jpg", elem_id="chat-room")
    with gr.Row(elem_classes="col-container"):
        with gr.Column(elem_id="history"):
            with gr.Row():
                add_dialog = gr.ClearButton(
                    components=[chat_his],
                    icon=base_url+r"icon\add_dialog.png",
                    # variant="primary",
                    value="New Dialog",
                    # min_width=5,
                    elem_id="btn_transparent",
                    size="sm"
                )
                delete_dialog = gr.Button(
                    icon=base_url+r"icon\delete_dialog.png",
                    value="Delete Dialog",
                    # min_width=5,
                    elem_id="btn_transparent",
                    size="sm",
                )
                His_choice_cache=get_all_conversation_names()
                current_select_value=list_vali_check(His_choice_cache)
                Historylist=gr.Radio(
                    #label="Dialog Box",
                    show_label=False,
                    interactive=True,
                    value=current_select_value,
                    choices=His_choice_cache,
                    elem_id="history-select-dropdown",
                )
        with gr.Column(scale=4):
            chatbot = gr.Chatbot(type='messages',elem_id="chatbot-messages",height='70vh',show_copy_all_button=True,show_copy_button=True,show_label=True)
            input_box = gr.Textbox(
                label="Your Message",
                placeholder="Enter your message here",
                interactive=True,
                elem_id="input-box",
            )
            send_btn = gr.Button("Send",variant="primary", elem_id="send-btn")

     

            
    # Chat Control
    send_btn.click(user, [input_box, chatbot], [input_box, chatbot]).then(
        bot, chatbot, chatbot, show_progress=True
    )
    input_box.submit(user, [input_box, chatbot], [input_box, chatbot]).success(input_box_submit_handle,[chatbot],[Historylist]).then(
        bot, chatbot, chatbot, show_progress=True
    )

    # Radio control
    add_dialog.click(
        new_conversation_to_json
    ).success(
        load_historylist,
        outputs=[Historylist]
    ).success(get_last_conversation_content_with_gid,
        [],
        [chatbot])

    delete_dialog.click(delete_conversation_with_gid_from_json_handle,
                        inputs=[Historylist]
                        ).success(load_historylist,
                        outputs=[Historylist]
                        ).success(get_last_conversation_content_with_gid,
                        [],
                        [chatbot])
    
    Historylist.select(lambda:gr.Radio(),[],[Historylist]
                       ).success(lambda Historylist: gr.Textbox(value=Historylist),
                                 [Historylist]
                                 ).success(get_selected_conversation_content_with_gid_handle,
                                            [Historylist],
                                           [chatbot])
    
    # chat_name.blur(
    #     modify_conversation_name,
    #     inputs=[Historylist,chat_name],
    #     outputs=[chat_name]
    # ).success(lambda chat_name: gr.Radio(
    #                     show_label=False,
    #                     interactive=True,
    #                     value=chat_name,
    #                     choices=get_all_conversation_names(),
    #                     ),
    #            inputs=chat_name,outputs=[Historylist]
    # )

    custom_footer_content = """
    <div style="text-align:center">  <!-- 外层容器整体居中 -->
        <div style="text-align:left display: inline-block">  <!-- 内层容器左对齐且内联块显示 -->
            ©Siemens Healthineers 2019 - 2025 - for internal use only | Powered by SSME IT<br>
            Technical Details<br>
            -Dev by:SSME IT<br>
            -Version:2.0.2<br>
        </div>
    </div>
    """
    gr.HTML(custom_footer_content)
    demo.load(load_userinfo, inputs=None, outputs=[Historylist]).success(get_selected_conversation_content_with_gid_handle,
                                                      [Historylist],
                                                      [chatbot])

def setup_gui(share: bool = False, auth_file: list = ["", ""], server_port=port) -> None:
    # 在启动前添加环境变量校验提示
    # print(model_id)
    try:
        demo.launch(server_name="0.0.0.0", inbrowser=True, share=share, server_port=server_port)
        # demo.load(load_userinfo)  # 界面加载时触发认证
        
    except ValueError as e:
        print(f"配置错误: {e}")
        print("请确保已设置以下环境变量:")
        print("1. AWS_ACCESS_KEY_ID")
        print("2. AWS_SECRET_ACCESS_KEY") 
        print("3. AWS_DEFAULT_REGION")
        raise


if __name__ == "__main__":
    setup_gui(share=True)
